home *** CD-ROM | disk | FTP | other *** search
- /* ScianNetObjects.c
- * John R. Murray
- * June 1992
- * Stuff for transmitting and receiving objects over sockets.
- */
-
- #include "Scian.h"
- #include "ScianIDs.h"
- #include "ScianTypes.h"
- #include "ScianNetObjects.h"
- #include "ScianSockets.h"
- #include "ScianLists.h"
- #include "ScianErrors.h"
- #include "ScianWindows.h"
- #include "ScianObjWindows.h"
- #include "ScianDatasets.h"
- #include "ScianNames.h"
- /* the following .h files are ONLY included for extern classes */
- #include "ScianArrays.h"
- #include "ScianTimers.h"
- #include "ScianVisObjects.h"
- /* this one's here for NewAtomicPalette function definition */
- #include "ScianColors.h"
-
- #ifndef DEBUGSOCKETS
- #define DEBUGSOCKETS
- #endif
-
- /* if the main body of the object is smaller than this, an obj without the
- * extra bytes gets sent */
- #define NO_SIZE_THRESHOLD 1024
-
- static ObjPtr allPublished;
- #ifdef SAVEDELETED
- static ObjPtr allDeletedPublished;
- #endif
-
- #ifdef SOCKETS
-
- unsigned int lastNetworkID = 0;
-
- unsigned long GetNetworkID()
- {
- return ++lastNetworkID;
- }
-
-
- void AssembleNetObjectVars (vnode, start)
- VarsPtr vnode;
- char **start;
- {
- if (!vnode)
- return;
-
- if (!ThisWouldBeAReallyBadThing(vnode -> name))
- {
-
- if (!vnode -> value)
- {
- fprintf(stderr, "WARNING!! Sending var %ld with value NULLOBJ\n", vnode -> name);
- }
-
- #ifdef DEBUGSOCKETS
- #ifdef DEBUG
- fprintf(stderr, "var %d\n", vnode -> name);
- #endif
- sprintf(*start, "%d ", vnode -> name);
- *start += strlen(*start);
- #else
- *((NameTyp *) *start) = HTON_NAMETYP(vnode -> name);
- *start += sizeof(NameTyp);
- #endif
- }
- AssembleNetObjectVars (vnode -> left, start);
- AssembleNetObjectVars (vnode -> right, start);
- }
-
- char *GetNetTypeStr(obj, connection)
- ObjPtr obj, connection;
- {
- ObjPtr class;
-
- class = ClassOf(obj);
-
- if (class == iconDataset)
- return NET_ICONDATASET;
- else if (class == icon1DVector)
- return NET_ICON1DVECTOR;
- else if (class == icon2DVector)
- return NET_ICON2DVECTOR;
- else if (class == icon3DVector)
- return NET_ICON3DVECTOR;
- else if (class == icon4DVector)
- return NET_ICON4DVECTOR;
- else if (class == icon1DScalar)
- return NET_ICON1DSCALAR;
- else if (class == icon2DScalar)
- return NET_ICON2DSCALAR;
- else if (class == icon3DScalar)
- return NET_ICON3DSCALAR;
- else if (class == icon4DScalar)
- return NET_ICON4DSCALAR;
- else if (class == data3DScalar)
- return NET_DATA3DSCALAR;
- else if (class == data2DScalar)
- return NET_DATA2DSCALAR;
- else if (class == data1DVector)
- return NET_DATA1DVECTOR;
- else if (class == data3DUnstructSurface)
- return NET_DATA3DUNSTRUCT;
- else if (class == datasetClass)
- return NET_DATASET;
- else if (class == dataFormClass)
- return NET_DATAFORM;
- else if (class == stringClass)
- return NET_STRING;
- else if (class == objClass && IsInt(obj))
- return NET_INTEGER;
- else if (class == objClass && IsReal(obj))
- return NET_REAL;
- else if (class == objClass)
- return NET_PLAINOBJECT;
- else if (class == arrayClass)
- #if MACHINE == IRIS4D
- #ifdef FASTSOCKETS
- return NET_REALARRAYRAW;
- #else
- if (GetPredicate(connection, FASTSOCKET))
- {
- return NET_REALARRAYRAW;
- }
- else
- {
- return NET_REALARRAYASCII;
- }
- #endif
- #else
- return NET_REALARRAYASCII;
- #endif
- else if (class == objectArrayClass)
- return NET_OBJECTARRAY;
- else if (class == timedObjClass)
- return NET_TIMEDOBJECT;
- else if (class == paletteClass)
- return NET_PALETTE;
- else if (class == visIcon)
- {
- fprintf(stderr, "sending visIcon\n");
- return NET_VISICON;
- }
- else
- {
- fprintf(stderr, "trying to transmit obj of unrecognized class\n");
- fprintf(stderr, "class = 0x%x\n", class);
- return NET_UNIMPLEMENTED;
- }
- }
-
- void TransmitObject(obj, connection, flag)
- ObjPtr obj, connection;
- Bool flag;
- /* transmit obj across connection. if flag, send OBJ! message header, or not */
- {
- char buf[1024];
- char *bufp;
- int sock;
- int networkID;
- ObjPtr networkIDPtr;
- NetFlagsTyp netFlags;
- FuncTyp method;
- FlagsTyp flagstmp;
-
- networkID = PublishObject(obj);
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- if (sock < 0)
- return;
-
- bufp = buf;
-
- if (flag)
- {
- sprintf(bufp, "%s ", NO_MESG_OBJECT);
- bufp += strlen(bufp);
- }
-
- /* sending network type identifier */
- sprintf(bufp, "%s ", GetNetTypeStr(obj, connection));
- bufp += strlen(bufp);
-
- /* sending network ID number */
- #ifdef DEBUG
- fprintf(stderr, "xmitting netid %ld\n", networkID);
- #endif
- sprintf(bufp, "%ld ", networkID);
- bufp += strlen(bufp);
-
- /* send object flags */
- flagstmp = obj -> flags;
- flagstmp = flagstmp & ~ISPUBLISHED;
- if (GetVar(obj, ADVERTISED))
- {
- flagstmp = flagstmp | ISREMOTEADVERTISED;
- }
- sprintf(bufp, "%ld ", flagstmp);
- bufp += strlen(bufp);
-
- /* send network flags */
- netFlags = ( !obj -> class ? NO_NULL_CLASS : 0 )
- | ( !obj -> vars ? NO_NULL_VARS : 0 )
- | ( !obj -> methods ? NO_NULL_METHODS : 0 )
- | ( !obj -> depends ? NO_NULL_DEPENDS : 0 );
-
- sprintf(bufp, "%ld ", netFlags);
- bufp += strlen(bufp);
-
- /* send variables */
- AssembleNetObjectVars(obj -> vars, &bufp);
- sprintf(bufp, "%d ", NO_LAST_VAR);
- bufp += strlen(bufp);
-
- #ifdef DEBUG
- fprintf(stderr, "%s", buf);
- #endif
-
- if (bufp - buf > 1024)
- {
- fprintf(stderr, "TransmitObject: overran buffer!\n");
- }
-
- writen(sock, buf, bufp - buf);
-
- method = GetMethod(obj, TRANSMITEXTRA);
- if (method)
- {
- /*BIG HAK!*/
- #if MACHINE == RS6000
- #else
- if (GetPredicate(connection, FASTSOCKET)
- && (method == TransmitExtraStuffRealArrayAscii))
- {
- #ifdef DEBUG
- fprintf(stderr, "fast\n");
- #endif
- TransmitExtraStuffRealArrayRaw(obj, connection);
- }
- else
- #endif
- {
- (* method) (obj, connection);
- }
- }
-
- /* send line terminator */
- buf[0] = '\n';
- buf[1] = '\0';
- #ifdef DEBUG
- fprintf(stderr, "%s", buf);
- #endif
-
- writen(sock, buf, strlen(buf));
-
- }
-
- #define ROS_BEGIN 0 /* startup state */
- #define ROS_READ_NET_TYPE 1 /* reading the type of this object */
- #define ROS_READ_FLAGS 2 /* reading the object flags */
- #define ROS_READ_NETFLAGS 3 /* reading the net flags */
- #define ROS_READ_VARS 4 /* reading the vars */
- #define ROS_ERROR 5 /* blammo */
- #define ROS_DONE 6 /* I'm done */
- #define ROS_READ_NETWORKID 7 /* reading the network identifier */
-
- ObjPtr ReceiveObject(connection, remoteChCount)
- ObjPtr connection;
- unsigned long remoteChCount;
- {
- int state;
- ObjPtr retVal;
- char objType, inChar;
- int someDigits;
- unsigned long ltmp;
- int networkID;
- int sock;
- char s[100];
- int netID = 0;
- int varNum = 0;
- int debug = 0; /* setting this to 1 will fprintf the internal states */
- ObjPtr process;
-
- ltmp = 0; /* we'll have to do something else with ltmp when we make this reentrant */
- state = ROS_BEGIN;
- sock = ((ConnectionPtr) connection) -> sock;
-
- if (sock < 0)
- {
- ReportError("ReceiveObject", "Bad socket");
- return ObjFalse;
- }
-
- process = GetObjectVar("ReceiveObject", connection, OWNERPROCESS);
- if (!process)
- {
- ReportError("ReceiveObject", "connection has no OWNERPROCESS");
- return ObjFalse;
- }
-
- while (state != ROS_DONE)
- {
- switch(state)
- {
- case ROS_BEGIN:
- if (debug) fprintf(stderr, "state = BEGIN\n");
- state = ROS_READ_NET_TYPE;
- s[0] = '\0';
- break;
- case ROS_READ_NET_TYPE: /* initial entry assumes s == "" */
- if (debug) fprintf(stderr, "state = READ_NET_TYPE\n");
- if (1 == read(sock, &inChar, 1))
- {
- #if 0
- if (inChar == '\n' || inChar == '\0')
- {
- ((ConnectionPtr) connection) -> gotCmdEnd = true;
- ltmp = 0;
- state = ROS_ERROR;
- }
- else
- #endif
- if (!isspace(inChar))
- {
- if (strlen(s) <= 4)
- {
- strncat(s, &inChar, 1); /* append one char */
- }
- else
- {
- state = ROS_ERROR; /* net type too long */
- }
- /* skip initial blanks */
- }
- else if (s[0] == '\0') /* no characters yet */
- {
- /* skip initial blanks */
- }
- else if (strlen(s) != 4)
- {
- state = ROS_ERROR;
- }
- else /* it's a space, and we've got 4 characters */
- {
- long cmdNum;
-
- cmdNum = CMD(s);
- if (cmdNum == CMD(NET_PLAINOBJECT))
- {
- retVal = NewObject(0, 0);
- }
- else if (cmdNum == CMD(NET_INTEGER))
- {
- retVal = NewInt(0);
- }
- else if (cmdNum == CMD(NET_REAL))
- {
- retVal = NewReal(0);
- }
- else if (cmdNum == CMD(NET_STRING))
- {
- retVal = NewString("");
- }
- #if MACHINE == IRIS4D
- else if (cmdNum == CMD(NET_REALARRAYRAW))
- {
- retVal = NewRealArray(1, 1L);
- SetMethod(retVal, TRANSMITEXTRA, TransmitExtraStuffRealArrayRaw);
- SetMethod(retVal, RECEIVEEXTRA, ReceiveExtraStuffRealArrayRaw);
- }
- #endif
- else if (cmdNum == CMD(NET_REALARRAYASCII))
- {
- retVal = NewRealArray(1, 1L);
- }
- else if (cmdNum == CMD(NET_OBJECTARRAY))
- {
- long dummy;
- dummy = 1L;
- retVal = NewArray(AT_OBJECT, 1, &dummy);
- }
- else if (cmdNum == CMD(NET_ICONDATASET))
- {
- retVal = NewObject(iconDataset, 0);
- }
- else if (cmdNum == CMD(NET_ICON1DVECTOR))
- {
- retVal = NewObject(icon1DVector, 0);
- }
- else if (cmdNum == CMD(NET_ICON2DVECTOR))
- {
- retVal = NewObject(icon2DVector, 0);
- }
- else if (cmdNum == CMD(NET_ICON3DVECTOR))
- {
- retVal = NewObject(icon3DVector, 0);
- }
- else if (cmdNum == CMD(NET_ICON4DVECTOR))
- {
- retVal = NewObject(icon4DVector, 0);
- }
- else if (cmdNum == CMD(NET_ICON1DSCALAR))
- {
- retVal = NewObject(icon1DScalar, 0);
- }
- else if (cmdNum == CMD(NET_ICON2DSCALAR))
- {
- retVal = NewObject(icon2DScalar, 0);
- }
- else if (cmdNum == CMD(NET_ICON3DSCALAR))
- {
- retVal = NewObject(icon3DScalar, 0);
- }
- else if (cmdNum == CMD(NET_ICON4DSCALAR))
- {
- retVal = NewObject(icon4DScalar, 0);
- }
- else if (cmdNum == CMD(NET_DATA1DVECTOR))
- {
- retVal = NewObject(data1DVector, 0);
- }
- else if (cmdNum == CMD(NET_DATA2DSCALAR))
- {
- retVal = NewObject(data2DScalar, 0);
- }
- else if (cmdNum == CMD(NET_DATA3DSCALAR))
- {
- retVal = NewObject(data3DScalar, 0);
- }
- else if (cmdNum == CMD(NET_DATA3DUNSTRUCT))
- {
- retVal = NewObject(data3DUnstructSurface, 0);
- }
- else if (cmdNum == CMD(NET_DATASET))
- {
- retVal = NewObject(datasetClass, 0);
- }
- else if (cmdNum == CMD(NET_DATAFORM))
- {
- retVal = NewObject(dataFormClass, 0);
- }
- else if (cmdNum == CMD(NET_TIMEDOBJECT))
- {
- retVal = NewObject(timedObjClass, 0);
- }
- else if (cmdNum == CMD(NET_PALETTE))
- {
- retVal = NewAtomicPalette();
- }
- else if (cmdNum == CMD(NET_VISICON))
- {
- retVal = NewObject(visIcon, 0);
- }
- else if (cmdNum == CMD(NET_UNIMPLEMENTED))
- {
- fprintf(stderr, "remote process transmitted unimplemented net type\ntreating it as plain object\n");
- retVal = NewObject(0, 0);
- }
- else
- {
- fprintf(stderr, "unrecognized net type %4s\n", s);
- return ObjFalse;
- }
- ltmp = 0;
- someDigits = false;
- state = ROS_READ_NETWORKID;
- }
- }
- break;
- case ROS_READ_NETWORKID: /* initial entry assumes ltmp == 0 && someDigits == false */
- if (debug) fprintf(stderr, "state = READ_NETWORKID\n");
- #ifdef DEBUGSOCKETS
- if (1 == read(sock, &inChar, 1))
- {
- if (isspace(inChar) && (inChar != '\n') && !someDigits)
- {
- /* skipping blanks */
- }
- else if (inChar >= '0' && inChar <= '9')
- {
- someDigits = true;
- ltmp *= 10;
- ltmp += inChar - '0';
- }
- else if (inChar == '\0' || inChar == '\n')
- {
- ((ConnectionPtr) connection) -> gotCmdEnd = true;
- state = ROS_ERROR;
- }
- else if (!someDigits)
- {
- state = ROS_ERROR;
- }
- else
- {
- if (debug) fprintf(stderr, "setting NETWORKID to %d\n", ltmp);
- networkID = ltmp;
- someDigits = false;
- ltmp = 0;
- state = ROS_READ_FLAGS;
- }
- }
- #else
- Yabbadabba!
- #endif
- break;
- case ROS_READ_FLAGS: /* 1st entry assumes ltmp == 0 & someDigits == false */
- if (debug) fprintf(stderr, "state = READ_FLAGS\n");
- #ifdef DEBUGSOCKETS
- if (1 == read(sock, &inChar, 1))
- {
- if (isspace(inChar) && (inChar != '\n') && !someDigits)
- {
- /* skipping blanks */
- }
- else if (inChar >= '0' && inChar <= '9')
- {
- someDigits = true;
- ltmp *= 10;
- ltmp += inChar - '0';
- }
- else if (inChar == '\0' || inChar == '\n')
- {
- ((ConnectionPtr) connection) -> gotCmdEnd = true;
- state = ROS_ERROR;
- }
- else
- {
- retVal -> flags = ltmp;
- ltmp = 0;
- someDigits = false;
- state = ROS_READ_NETFLAGS;
- }
- }
- #else
- Yabbadabba!
- #endif
- break;
- case ROS_READ_NETFLAGS: /* initial entry assumes ltmp == 0 && someDigits == false */
- if (debug) fprintf(stderr, "state = READ_NETFLAGS\n");
- #ifdef DEBUGSOCKETS
- if (1 == read(sock, &inChar,1))
- {
- if (isspace(inChar) && (inChar != '\n') && !someDigits)
- {
- /* skipping blanks */
- }
- else if (inChar >= '0' && inChar <= '9')
- {
- someDigits = true;
- ltmp *= 10;
- ltmp += inChar - '0';
- }
- else if (inChar == '\n' || inChar == '\0')
- {
- ((ConnectionPtr) connection) -> gotCmdEnd = true;
- state = ROS_ERROR;
- }
- else
- {
- /* done reading netflags */
- if (debug) fprintf(stderr, "object's netflags == %lx\n", ltmp);
- if (ltmp & NO_NULL_CLASS)
- {
- /* ignored for now */
- }
-
- if (ltmp & NO_NULL_VARS)
- {
- /* ignored for now */
- }
-
- if (ltmp & NO_NULL_METHODS)
- {
- /* ignored */
- }
-
- if (ltmp & NO_NULL_DEPENDS)
- {
- /* ignored */
- }
-
- ltmp = 0;
- someDigits = false;
- state = ROS_READ_VARS;
- }
- }
- #else
- Yabbadabba!
- #endif
- break;
- case ROS_READ_VARS: /* initial entry assumes ltmp == 0 and someDigits == false */
- /* if (debug) fprintf(stderr, "state = READ_VARS\n"); */
- if (debug) fprintf(stderr, "state = READ_VARS... ");
- if (1 == read(sock, &inChar, 1))
- {
- if (debug) fprintf(stderr, "char '%c'\n", inChar);
- if (isspace(inChar) && (inChar != '\n') && !someDigits)
- {
- /* skipping blanks */
- }
- else if (inChar >= '0' && inChar <= '9')
- {
- someDigits = true;
- ltmp *= 10;
- ltmp += inChar - '0';
- }
- else if (inChar == '\n' || inChar == '\0')
- {
- ((ConnectionPtr) connection) -> gotCmdEnd = true;
- state = ROS_ERROR;
- }
- else if (ltmp != NO_LAST_VAR)
- {
- VarsPtr vPtr;
- SetVar (retVal, ltmp, NULLOBJ);
- vPtr = GetVarNode(retVal, ltmp);
- vPtr -> process = process;
- vPtr -> remoteNetID = NETSTUBFLAG;
- vPtr -> remoteChCount = anotherDamnReferenceCount;
- ltmp = 0;
- someDigits = false;
- }
- else
- {
- /* that may have been the end var marker */
- if (someDigits)
- {
- if (SanityCheckObject(retVal))
- {
- FuncTyp method;
-
- method = GetMethod(retVal, RECEIVEEXTRA);
- if (method)
- {
- (* method) (retVal, connection);
- }
- state = ROS_DONE;
- }
- else
- {
- ReportError("ReceiveObject", "An incoming network object failed Sanity Check");
- state = ROS_ERROR;
- }
- }
- else
- {
- state = ROS_ERROR;
- }
- }
- }
- break;
- case ROS_ERROR: /* no assumptions on inital entry */
- if (debug) fprintf(stderr, "state = ERROR\n");
- ReportError("ReceiveObject", "Error in receiving network object");
- return ObjFalse;
- break;
- default:
- fprintf(stderr, "funny state in ReceiveObject!\n");
- break;
- }
- }
-
- SetVar(retVal, NETWORKID, NewInt(networkID));
- if (remoteChCount) SetVar(retVal, REMOTECHCOUNT, NewInt(remoteChCount));
- SetVar(retVal, OWNERCONNECTION, connection);
- retVal -> flags = retVal -> flags | ISREMOTE;
- if (debug) PrintObject(retVal);
- if (debug) PrintVarTree(retVal);
- NetworkIDIsWaiting(process, networkID, false);
- return retVal;
- }
-
- real ReceiveRealAscii(connection)
- ObjPtr connection;
- {
- real retVal;
- int sock;
- char inChar, s[100];
- int si;
- double time;
- Bool someDigits;
-
- si = 0;
- s[si] = '\0';
- someDigits = false;
- time = Clock();
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- while (Clock() < time + JOHNSTIMEOUT && !((ConnectionPtr) connection) -> gotCmdEnd)
- {
- if (1 == read(sock, &inChar, 1))
- {
- if (isspace(inChar) && (inChar != '\n') && !someDigits)
- {
- /* skipping blanks */
- }
- else if (si >= 100 || (inChar >= '0' && inChar <= '9')
- || inChar == '-' || inChar == 'e' || inChar == 'E'
- || inChar == '+' || inChar == '-' || inChar == '.')
- {
- someDigits = true;
- s[si++] = inChar;
- s[si] = '\0';
- }
- else
- {
- int len;
-
- if (inChar == '\0' || inChar == '\n')
- {
- ((ConnectionPtr) connection) -> gotCmdEnd = true;
- }
-
- /* make sure we read etwas that takes up the whole string */
- if (someDigits && (1 != sscanf(s, "%100g%n", &retVal, &len)
- || len < strlen(s)))
- {
- fprintf(stderr, "bad sscanf return. s = %s, len = %d, strlen(s) = %d.\n", s, len, strlen(s));
- return -1;
- }
- return retVal;
- }
- }
- }
- /* only got here if we timed out */
- fprintf(stderr, "hack timeout in ReceiveRealAscii\n");
- return -1;
- }
-
- ObjPtr TransmitExtraStuffRealArrayRaw(obj, connection)
- ObjPtr obj, connection;
- {
- int sock;
- int rank;
- long *dimp;
- int i;
- long nels;
- real *elsPtr;
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- rank = RANK(obj);
- #ifdef DEBUG
- fprintf(stderr, "sending rank = %d.. ", rank);
- #endif
- writen(sock, (char *) &rank, sizeof(rank));
-
- #ifdef DEBUG
- fprintf(stderr, "sending dims");
- #endif
- dimp = DIMS(obj);
- nels = 1;
- for (i = 0; i < rank; ++i)
- {
- #ifdef DEBUG
- fprintf(stderr, " d%d=%ld", i, *dimp);
- #endif
- writen(sock, (char *) dimp, sizeof(*dimp));
- nels *= *dimp;
- ++dimp;
- }
- #ifdef DEBUG
- fprintf(stderr, ". done with dims\n");
- fprintf(stderr, "trying to write %ld * 4 bytes of data\n", nels);
- #endif
- elsPtr = ELEMENTS(obj);
- writen(sock, (char *) elsPtr, sizeof(*elsPtr) * nels);
- }
-
- ObjPtr ReceiveExtraStuffRealArrayRaw(obj, connection)
- ObjPtr obj, connection;
- {
- int sock, rank, i;
- long *dimp, nels, oneDim;
- real *elsPtr;
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- readn(sock, (char *) &rank, sizeof(rank));
- /* fprintf(stderr, "rank = %ld\n", */
- #ifdef DEBUG
- fprintf(stderr, "got rank = %d\n", rank);
- #endif
- RANK(obj) = rank;
-
- #ifdef DEBUG
- fprintf(stderr, "getting dims -");
- #endif
- dimp = Alloc(rank * sizeof(long));
- DIMS(obj) = dimp;
- nels = 1;
- for (i = 0; i < rank; ++i)
- {
- readn(sock, (char *) &oneDim, sizeof(long));
- nels *= oneDim;
- *dimp = oneDim;
- ++dimp;
- #ifdef DEBUG
- fprintf(stderr, " d%d=%ld", i, oneDim);
- #endif
- }
- #ifdef DEBUG
- fprintf(stderr, ". done with dims\n");
- #endif
-
- elsPtr = (void *) Alloc(nels * sizeof(real));
- if (!elsPtr)
- {
- OMErr();
- return ObjFalse;
- }
- ELEMENTS(obj) = elsPtr;
-
- #ifdef DEBUG
- fprintf(stderr, "trying to read 4 * %d bytes\n", nels);
- #endif
- readn(sock, (char *) elsPtr, sizeof(real) * nels);
- #ifdef DEBUG
- fprintf(stderr, "...wow! did it work??\n");
- #endif
- }
-
- ObjPtr TransmitExtraStuffRealArrayAscii(obj, connection)
- ObjPtr obj, connection;
- {
- int sock;
- int rank;
- long *dimp;
- long i;
- long nels;
- real *elsPtr;
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- rank = RANK(obj);
- #ifdef DEBUG
- fprintf(stderr, "sending rank = %d.. ", rank);
- #endif
- sprintf(tempStr, "%d ", rank);
- writen(sock, tempStr, strlen(tempStr));
-
- #ifdef DEBUG
- fprintf(stderr, "sending dims");
- #endif
- dimp = DIMS(obj);
- nels = 1;
- for (i = 0; i < rank; ++i)
- {
- #ifdef DEBUG
- fprintf(stderr, " d%d=%ld", i, *dimp);
- #endif
- sprintf(tempStr, "%ld ", *dimp);
- writen(sock, tempStr, strlen(tempStr));
- nels *= *dimp;
- ++dimp;
- }
- #ifdef DEBUG
- fprintf(stderr, ". done with dims\n");
- fprintf(stderr, "trying to write %ld ascii numbers\n", nels);
- #endif
- elsPtr = ELEMENTS(obj);
- for (i = 0; i < nels; ++i)
- {
- sprintf(tempStr, "%g ", elsPtr[i]);
- writen(sock, tempStr, strlen(tempStr));
- }
- }
-
- ObjPtr ReceiveExtraStuffRealArrayAscii(obj, connection)
- ObjPtr obj, connection;
- {
- int sock, rank, i;
- long *dimp, nels, oneDim;
- real *elsPtr;
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- rank = ReceiveRealAscii(connection);
- #ifdef DEBUG
- fprintf(stderr, "got rank = %d\n", rank);
- #endif
- RANK(obj) = rank;
-
- #ifdef DEBUG
- fprintf(stderr, "getting dims -");
- #endif
- dimp = Alloc(rank * sizeof(long));
- DIMS(obj) = dimp;
- nels = 1;
- for (i = 0; i < rank; ++i)
- {
- oneDim = ReceiveRealAscii(connection);
- nels *= oneDim;
- *dimp = oneDim;
- ++dimp;
- #ifdef DEBUG
- fprintf(stderr, " d%d=%ld", i, oneDim);
- #endif
- }
- #ifdef DEBUG
- fprintf(stderr, ". done with dims\n");
- #endif
-
- elsPtr = (void *) Alloc(nels * sizeof(real));
- if (!elsPtr)
- {
- OMErr();
- return ObjFalse;
- }
-
- ELEMENTS(obj) = elsPtr;
- #ifdef DEBUG
- fprintf(stderr, "trying to read %ld elements..", nels);
- #endif
- for (i = 0; i < nels; ++i)
- {
- elsPtr[i] = ReceiveRealAscii(connection);
- }
- #ifdef DEBUG
- fprintf(stderr, "wow! did it work??\n");
- #endif
- return ObjTrue;
- }
-
- ObjPtr TransmitExtraStuffObjectArraySpecial(obj, connection)
- ObjPtr obj, connection;
- {
- int sock;
- int rank;
- long *dimp;
- long i;
- long nels;
- ObjPtr *elsPtr;
- double startTime;
-
- startTime = Clock();
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- rank = RANK(obj);
- #ifdef DEBUG
- fprintf(stderr, "sending rank = %d.. ", rank);
- #endif
- sprintf(tempStr, "%d ", rank);
- writen(sock, tempStr, strlen(tempStr));
-
- #ifdef DEBUG
- fprintf(stderr, "sending dims");
- #endif
- dimp = DIMS(obj);
- nels = 1;
- for (i = 0; i < rank; ++i)
- {
- #ifdef DEBUG
- fprintf(stderr, " d%d=%ld", i, *dimp);
- #endif
- sprintf(tempStr, "%ld ", *dimp);
- writen(sock, tempStr, strlen(tempStr));
- nels *= *dimp;
- ++dimp;
- }
- #ifdef DEBUG
- fprintf(stderr, ". done with dims\n");
- #endif
-
- elsPtr = ELEMENTS(obj);
- for (i = 0; i < nels; ++i)
- {
- TransmitObject(elsPtr[i], connection, false);
- }
- fprintf(stderr, "object array transmit time %10.4lf\n", Clock() - startTime);
- }
-
- ObjPtr ReceiveExtraStuffObjectArraySpecial(obj, connection)
- ObjPtr obj, connection;
- {
- int sock, rank, i;
- long *dimp, nels, oneDim;
- ObjPtr *elsPtr;
- double startTime;
-
- startTime = Clock();
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- rank = ReceiveRealAscii(connection);
- #ifdef DEBUG
- fprintf(stderr, "got rank = %d\n", rank);
- #endif
- RANK(obj) = rank;
-
- #ifdef DEBUG
- fprintf(stderr, "getting dims -");
- #endif
- dimp = Alloc(rank * sizeof(long));
- DIMS(obj) = dimp;
- nels = 1;
- for (i = 0; i < rank; ++i)
- {
- oneDim = ReceiveRealAscii(connection);
- nels *= oneDim;
- *dimp = oneDim;
- ++dimp;
- #ifdef DEBUG
- fprintf(stderr, " d%d=%ld", i, oneDim);
- #endif
- }
- #ifdef DEBUG
- fprintf(stderr, ". done with dims\n");
- #endif
-
- elsPtr = (void *) Alloc(nels * sizeof(ObjPtr));
- if (!elsPtr)
- {
- OMErr();
- return ObjFalse;
- }
-
- ELEMENTS(obj) = elsPtr;
- for (i = 0; i < nels; ++i)
- {
- ((ConnectionPtr) connection) -> gotCmdEnd = false;
- elsPtr[i] = ReceiveObject(connection, 0);
- }
- fprintf(stderr, "object array receive time %10.4lf\n", Clock() - startTime);
- return ObjTrue;
- }
-
- #if 1
- ObjPtr TransmitExtraStuffObjectArray(obj, connection)
- ObjPtr obj, connection;
- {
- TransmitExtraStuffObjectArraySpecial(obj, connection);
- }
- #else
- ObjPtr TransmitExtraStuffObjectArray(obj, connection)
- ObjPtr obj, connection;
- {
- int sock;
- int rank;
- long *dimp;
- long i;
- long nels;
- real *elsPtr;
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- rank = RANK(obj);
- #ifdef DEBUG
- fprintf(stderr, "sending rank = %d.. ", rank);
- #endif
- sprintf(tempStr, "%d ", rank);
- writen(sock, tempStr, strlen(tempStr));
-
- #ifdef DEBUG
- fprintf(stderr, "sending dims");
- #endif
- dimp = DIMS(obj);
- nels = 1;
- for (i = 0; i < rank; ++i)
- {
- #ifdef DEBUG
- fprintf(stderr, " d%d=%ld", i, *dimp);
- #endif
- sprintf(tempStr, "%ld ", *dimp);
- writen(sock, tempStr, strlen(tempStr));
- nels *= *dimp;
- ++dimp;
- }
- #ifdef DEBUG
- fprintf(stderr, ". done with dims\n");
- #endif
- }
- #endif
-
- #if 1
- ObjPtr ReceiveExtraStuffObjectArray(obj, connection)
- ObjPtr obj, connection;
- {
- ReceiveExtraStuffObjectArraySpecial(obj, connection);
- }
- #else
- ObjPtr ReceiveExtraStuffObjectArray(obj, connection)
- ObjPtr obj, connection;
- {
- int sock, rank, i;
- long *dimp, nels, oneDim;
- ObjPtr *elsPtr;
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- rank = ReceiveRealAscii(connection);
- #ifdef DEBUG
- fprintf(stderr, "got rank = %d\n", rank);
- #endif
- RANK(obj) = rank;
-
- #ifdef DEBUG
- fprintf(stderr, "getting dims -");
- #endif
- dimp = Alloc(rank * sizeof(long));
- DIMS(obj) = dimp;
- nels = 1;
- for (i = 0; i < rank; ++i)
- {
- oneDim = ReceiveRealAscii(connection);
- nels *= oneDim;
- *dimp = oneDim;
- ++dimp;
- #ifdef DEBUG
- fprintf(stderr, " d%d=%ld", i, oneDim);
- #endif
- }
- #ifdef DEBUG
- fprintf(stderr, ". done with dims\n");
- #endif
-
- elsPtr = (void *) Alloc(nels * sizeof(ObjPtr));
- if (!elsPtr)
- {
- OMErr();
- return ObjFalse;
- }
-
- ELEMENTS(obj) = elsPtr;
- for (i = 0; i < nels; ++i)
- {
- elsPtr[i] = (ObjPtr) NETSTUBFLAG;
- }
- return ObjTrue;
- }
- #endif
-
- ObjPtr TransmitExtraStuffString(obj, connection)
- ObjPtr obj, connection;
- {
- int sock;
-
- if (!obj)
- return ObjFalse;
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- if (sock < 0)
- return ObjFalse;
-
- /* HAK! should figure out a way to avoid relying on the \0 */
- /* transmit everything, even the \0 on the end */
- #ifdef DEBUG
- fprintf(stderr, "%s", ((SPtr) obj) -> stringPtr);
- #endif
- writen(sock, ((SPtr) obj) -> stringPtr, 1 + strlen(((SPtr) obj) -> stringPtr));
- return ObjTrue;
- }
-
- ObjPtr ReceiveExtraStuffString(obj, connection)
- ObjPtr obj, connection;
- {
- double time;
- int sock;
- char inChar;
- int someDigits;
-
- /* HAK! figure out how to do this reentrantly */
- time = Clock();
- sock = ((ConnectionPtr) connection) -> sock;
- someDigits = false;
-
- if (obj)
- {
- char s[1000];
- int si;
-
- si = 0;
- s[si] = '\0';
-
- Free(((SPtr) obj) -> stringPtr); /* really! */
- ((SPtr) obj) -> stringPtr = (char *) 0;
-
- while(Clock() < time + JOHNSTIMEOUT)
- {
- if (1 == read(sock, &inChar, 1))
- {
- if (inChar)
- {
- someDigits = true;
- s[si++] = inChar;
- s[si] = '\0';
- }
-
- if (!inChar || si >= 999)
- {
- if ( ! ((SPtr) obj) -> stringPtr)
- {
- ((SPtr) obj) -> stringPtr = Alloc(1 + strlen(s));
- if (! ((SPtr) obj) -> stringPtr)
- {
- OMErr();
- return ObjFalse;
- }
- strcpy(((SPtr) obj) -> stringPtr, s);
- }
- else
- {
- ((SPtr) obj) -> stringPtr = Realloc(((SPtr) obj) -> stringPtr, strlen(s));
- if (! ((SPtr) obj) -> stringPtr)
- {
- OMErr();
- return ObjFalse;
- }
- strcat(((SPtr) obj) -> stringPtr, s);
- }
- si = 0;
- s[si] = '\0';
- }
-
- if (!inChar)
- {
- return ObjTrue;
- }
- }
- }
- /* only got here if we timed out */
- fprintf(stderr, "hack timeout in ReceiveExtraStuffString");
- return ObjFalse;
- }
- return ObjTrue;
- }
-
- ObjPtr TransmitExtraStuffObject(obj, connection)
- ObjPtr obj, connection;
- {
- int sock;
-
- if (!obj)
- return ObjFalse;
-
- sock = ((ConnectionPtr) connection) -> sock;
- if (sock < 0)
- return ObjFalse;
-
- if (IsInt(obj))
- {
- char buf[50];
-
- sprintf(buf, "%d ", ((IPtr) obj) -> intpart);
- #ifdef DEBUG
- fprintf(stderr, "%s", buf);
- #endif
- writen(sock, buf, strlen(buf));
- }
- else if (IsReal(obj))
- {
- char buf[100];
-
- sprintf(buf, "%g ", ((RPtr) obj) -> realpart);
- #ifdef DEBUG
- fprintf(stderr, "%s", buf);
- #endif
- writen(sock, buf, strlen(buf));
- }
- return ObjTrue;
- }
-
- ObjPtr ReceiveExtraStuffObject(obj, connection)
- ObjPtr obj, connection;
- {
- int sock;
- char inChar;
- int someDigits;
- long int ltmp;
- double time;
-
- if (!obj)
- return ObjFalse;
-
- /* HAK! figure out how to do this reentrantly */
- time = Clock();
-
- ltmp = 0;
- someDigits = false;
- inChar = 'x';
-
- sock = ((ConnectionPtr) connection) -> sock;
-
- if (IsInt(obj))
- {
- while (Clock() < time + JOHNSTIMEOUT)
- {
- if (1 == read(sock, &inChar, 1))
- {
- if (isspace(inChar) && (inChar != '\n') && !someDigits)
- {
- /* skipping blanks */
- }
- else if (inChar >= '0' && inChar <= '9')
- {
- someDigits = true;
- ltmp *= 10;
- ltmp += inChar - '0';
- }
- else if (inChar == '\0' || inChar == '\n')
- {
- ((ConnectionPtr) connection) -> gotCmdEnd = true;
- return ObjFalse;
- }
- else
- {
- ((IPtr) obj) -> intpart = ltmp;
- return ObjTrue;
- }
- }
- }
- /* only got here if we timed out */
- fprintf(stderr, "hack timeout in ReceiveExtraStuffObject");
- return ObjFalse;
- }
- else if (IsReal(obj))
- {
- ((RPtr) obj) -> realpart = ReceiveRealAscii(connection);
- }
-
- return ObjTrue;
- }
-
- #ifdef PROTO
- ObjPtr TransmitExtraStuffPalette(ObjPtr obj, ObjPtr connection)
- #else
- ObjPtr TransmitExtraStuffPalette(obj, connection)
- ObjPtr obj, connection;
- #endif
- {
- return ObjTrue;
- }
-
- #ifdef PROTO
- ObjPtr ReceiveExtraStuffPalette(ObjPtr obj, ObjPtr connection)
- #else
- ObjPtr ReceiveExtraStuffPalette(obj, connection)
- ObjPtr obj, connection;
- #endif
- {
- ObjPtr atomPal;
-
- #if 0
- atomPal = NewAtomicPalette(); /* HAK */
- CopyPalette(obj, atomPal);
- #endif
- return ObjTrue;
- }
-
- #endif /* ifdef SOCKETS */
-
- int PublishObject(obj)
- ObjPtr obj;
- /* Marks an object as published. Returns the (new?) NetworkID of the object,
- * or 0 if it failed for some reason.
- */
- {
- int netid;
-
- netid = 0;
- #ifdef SOCKETS
- if (!GetVar(obj, NETWORKID))
- {
- SetVar(obj, NETWORKID, NewInt(GetNetworkID()));
- }
- netid = GetInt(GetIntVar("PublishObject", obj, NETWORKID));
-
- if (!IsPublished(obj))
- {
- obj -> flags = obj -> flags | ISPUBLISHED;
- if (!allPublished)
- {
- fprintf(stderr, "Whoops! recreating allPublished!\n");
- allPublished = NewList();
- AddToReferenceList(allPublished);
- }
-
- PrefixList(allPublished, obj);
- }
- #endif
- return netid;
- }
-
- #if 0
- void UnPublishObject(obj)
- ObjPtr obj;
- /* Unmarks the published flag, removes object from published list */
- {
- #ifdef SOCKETS
- if (IsPublished(obj))
- {
- #if 0
- obj -> flags = obj -> flags & ~ISPUBLISHED;
- #endif
- DeleteFromList(allPublished, obj);
- DeleteFromList(allAdvertised, obj);
- #ifdef SAVEDELETED
- if (!allDeletedPublished);
- {
- fprintf(stderr, "Whoops! recreating allDeletedPublished!\n");
- allDeletedPublished = NewList();
- AddToReferenceList(allDeletedPublished);
- }
- PrefixList(allDeletedPublished, obj);
- #endif
- }
- #endif
- }
- #endif
-
- ObjPtr FindPublishedObject(num)
- unsigned long num;
- {
- #ifdef SOCKETS
- ObjPtr retVal;
- ThingListPtr runner;
-
- retVal = ObjFalse;
-
- if (allPublished)
- {
-
- runner = LISTOF(allPublished);
- while (runner && (num != GetInt(GetIntVar("FindPublishedObject", runner -> thing, NETWORKID))))
- {
- runner = runner -> next;
- }
- if (runner)
- {
- retVal = runner -> thing;
- }
- }
-
- /* if we didn't find it, try the list of Advertised objects */
- if (!retVal && allAdvertised)
- {
- runner = LISTOF(allAdvertised);
- while (runner && (num != GetInt(GetIntVar("FindPublishedObject", runner -> thing, NETWORKID))))
- {
- runner = runner -> next;
- }
- if (runner)
- {
- retVal = runner -> thing;
- }
- }
-
- #ifdef SAVEDELETED
- /* still not found, try the deleted list */
- if (retVal && allDeletedPublished)
- {
- runner = LISTOF(allDeletedPublished);
- while(runner && (num != GetInt(GetIntVar("FindPublishedObject", runner -> thing, NETWORKID))))
- {
- runner = runner -> next;
- }
- if (runner)
- {
- retVal = runner -> thing;
- }
- }
- #endif
-
- return retVal;
- #else
- return ObjFalse;
- #endif
- }
-
- void InitNetObjects()
- {
- #ifdef SOCKETS
- SetMethod(objClass, TRANSMITEXTRA, TransmitExtraStuffObject);
- SetMethod(objClass, RECEIVEEXTRA, ReceiveExtraStuffObject);
-
- SetMethod(stringClass, TRANSMITEXTRA, TransmitExtraStuffString);
- SetMethod(stringClass, RECEIVEEXTRA, ReceiveExtraStuffString);
-
- SetMethod(paletteClass, TRANSMITEXTRA, TransmitExtraStuffPalette);
- SetMethod(paletteClass, RECEIVEEXTRA, ReceiveExtraStuffPalette);
-
- SetMethod(objectArrayClass, TRANSMITEXTRA, TransmitExtraStuffObjectArraySpecial);
- SetMethod(objectArrayClass, RECEIVEEXTRA, ReceiveExtraStuffObjectArraySpecial);
-
- allPublished = NewList();
- AddToReferenceList (allPublished);
- #ifdef SAVEDELETED
- allDeletedPublished = NewList();
- AddToReferenceList (allDeletedPublished);
- #endif
-
- #endif
- }
-
- void KillNetObjects()
- {
- #ifdef SOCKETS
- RemoveFromReferenceList(allPublished);
- #endif
- }
-